<html>
	<head>
		<script src='https://surikov.github.io/webaudiofontdata/sound/0000_SoundBlasterOld_sf2.js'></script>
		<script>
			/*var afterTime = 0.05;
			var nearZero = 0.000001;
			function noZeroVolume (n) {
				if (n > nearZero) {
					return n;
				} else {
					return nearZero;
				}
			};
			function setupEnvelope (audioContext, envelope, zone, volume, when, sampleDuration, noteDuration) {
				envelope.gain.setValueAtTime(noZeroVolume(0), audioContext.currentTime);
				var lastTime = 0;
				var lastVolume = 0;
				var duration = noteDuration;
				var ahdsr = zone.ahdsr;
				if (sampleDuration < duration + afterTime) {
					duration = sampleDuration - afterTime;
				}
				if (ahdsr) {
					if (!(ahdsr.length > 0)) {
						ahdsr = [{
								duration: 0,
								volume: 1
							}, {
								duration: 0.5,
								volume: 1
							}, {
								duration: 1.5,
								volume: 0.5
							}, {
								duration: 3,
								volume: 0
							}
						];
					}
				} else {
					ahdsr = [{
							duration: 0,
							volume: 1
						}, {
							duration: duration,
							volume: 1
						}
					];
				}
				envelope.gain.cancelScheduledValues(when);
				envelope.gain.setValueAtTime(noZeroVolume(ahdsr[0].volume * volume), when);
				for (var i = 0; i < ahdsr.length; i++) {
					if (ahdsr[i].duration > 0) {
						if (ahdsr[i].duration + lastTime > duration) {
							var r = 1 - (ahdsr[i].duration + lastTime - duration) / ahdsr[i].duration;
							var n = lastVolume - r * (lastVolume - ahdsr[i].volume);
							envelope.gain.linearRampToValueAtTime(noZeroVolume(volume * n), when + duration);
							break;
						}
						lastTime = lastTime + ahdsr[i].duration;
						lastVolume = ahdsr[i].volume;
						envelope.gain.linearRampToValueAtTime(noZeroVolume(volume * lastVolume), when + lastTime);
					}
				}
				envelope.gain.linearRampToValueAtTime(noZeroVolume(0), when + duration + afterTime);
			};
			function findEnvelope(audioContext, target, when, duration) {
				var envelope = null;
				if (!(envelope)) {
					envelope = audioContext.createGain();
					envelope.target = target;
					envelope.connect(target);
					envelope.cancel = function () {
						if (envelope.when + envelope.duration > audioContext.currentTime) {
							envelope.gain.cancelScheduledValues(0);
							envelope.gain.setTargetAtTime(0.00001, audioContext.currentTime, 0.1);
							envelope.when = audioContext.currentTime + 0.00001;
							envelope.duration = 0;
						}
					};
				}
				return envelope;
			};*/
			function numValue (aValue, defValue) {
				if (typeof aValue === "number") {
					return aValue;
				} else {
					return defValue;
				}
			};
			function adjustZone (audioContext, zone) {
				if (zone.buffer) {
					//
				} else {
					zone.delay = 0;
					if (zone.sample) {
						var decoded = atob(zone.sample);
						console.log('decoded',decoded);
						zone.buffer = audioContext.createBuffer(1, decoded.length / 2, zone.sampleRate);
						var float32Array = zone.buffer.getChannelData(0);
						var b1,
						b2,
						n;
						for (var i = 0; i < decoded.length / 2; i++) {
							b1 = decoded.charCodeAt(i * 2);
							b2 = decoded.charCodeAt(i * 2 + 1);
							if (b1 < 0) {
								b1 = 256 + b1;
							}
							if (b2 < 0) {
								b2 = 256 + b2;
							}
							n = b2 * 256 + b1;
							if (n >= 65536 / 2) {
								n = n - 65536;
							}
							float32Array[i] = n / 65536.0;
						}
						console.log('float32Array',float32Array);
					} else {
						if (zone.file) {
							var datalen = zone.file.length;
							var arraybuffer = new ArrayBuffer(datalen);
							var view = new Uint8Array(arraybuffer);
							var decoded = atob(zone.file);
							var b;
							for (var i = 0; i < decoded.length; i++) {
								b = decoded.charCodeAt(i);
								view[i] = b;
							}
							audioContext.decodeAudioData(arraybuffer, function (audioBuffer) {
								zone.buffer = audioBuffer;
							});
						}
					}
					zone.loopStart = numValue(zone.loopStart, 0);
					zone.loopEnd = numValue(zone.loopEnd, 0);
					zone.coarseTune = numValue(zone.coarseTune, 0);
					zone.fineTune = numValue(zone.fineTune, 0);
					zone.originalPitch = numValue(zone.originalPitch, 6000);
					zone.sampleRate = numValue(zone.sampleRate, 44100);
					zone.sustain = numValue(zone.originalPitch, 0);
				}
			};/*
			function findZone (audioContext, preset, pitch) {
				var zone = null;
				for (var i = preset.zones.length - 1; i >= 0; i--) {
					zone = preset.zones[i];
					if (zone.keyRangeLow <= pitch && zone.keyRangeHigh + 1 >= pitch) {
						break;
					}
				}
				try {
					adjustZone(audioContext, zone);
				} catch (ex) {
					console.log('adjustZone', ex);
				}
				return zone;
			};
			function limitVolume (volume) {
				if (volume) {
					volume = 1.0 * volume;
				} else {
					volume = 0.5;
				}
				return volume;
			};*/
			function queueWaveTable(audioContext, target, preset, when, pitch, duration, volume, slides) {
				if (audioContext.state == 'suspended') {
					console.log('audioContext.resume');
					audioContext.resume();
				}
				/*volume = limitVolume(volume);
				var zone = findZone(audioContext, preset, pitch);
				if (!(zone.buffer)) {
					console.log('empty buffer ', zone);
					return;
				}*/
				//var baseDetune = zone.originalPitch - 100.0 * zone.coarseTune - zone.fineTune;
				//var playbackRate = 1.0 * Math.pow(2, (100.0 * pitch - baseDetune) / 1200.0);
				//var sampleRatio = zone.sampleRate / audioContext.sampleRate;
				/*var startWhen = when;
				if (startWhen < audioContext.currentTime) {
					startWhen = audioContext.currentTime;
				}*/
				//var waveDuration = duration + afterTime;
				/*var loop = true;
				if (zone.loopStart < 1 || zone.loopStart >= zone.loopEnd) {
					loop = false;
				}
				if (!loop) {
					if (waveDuration > zone.buffer.duration / playbackRate) {
						waveDuration = zone.buffer.duration / playbackRate;
					}
				}*/
				//var envelope = findEnvelope(audioContext, target, startWhen, waveDuration);
				//setupEnvelope(audioContext, envelope, zone, volume, startWhen, waveDuration, duration);
				//envelope.audioBufferSourceNode = audioContext.createBufferSource();
				var envelope_audioBufferSourceNode = audioContext.createBufferSource();
				//envelope.audioBufferSourceNode.playbackRate.setValueAtTime(playbackRate, 0);
				/*if (slides) {
					if (slides.length > 0) {
						envelope.audioBufferSourceNode.playbackRate.setValueAtTime(playbackRate, when);
						for (var i = 0; i < slides.length; i++) {
							var newPlaybackRate = 1.0 * Math.pow(2, (100.0 * slides[i].pitch - baseDetune) / 1200.0);
							var newWhen = when + slides[i].when;
							envelope.audioBufferSourceNode.playbackRate.linearRampToValueAtTime(newPlaybackRate, newWhen);
						}
					}
				}*/
				console.log('preset',preset);
				var zone1=preset.zones[1];
				adjustZone(audioContext,zone1);
				envelope_audioBufferSourceNode.buffer = zone1.buffer;
				console.log('buffer',envelope_audioBufferSourceNode.buffer);
				/*for(var i=0;i<100;i++){
					console.log(envelope_audioBufferSourceNode.getChannelData()[i]);
				}*/
				/*if (loop) {
					envelope.audioBufferSourceNode.loop = true;
					envelope.audioBufferSourceNode.loopStart = zone.loopStart / zone.sampleRate + zone.delay;
					envelope.audioBufferSourceNode.loopEnd = zone.loopEnd / zone.sampleRate + zone.delay;
				} else {*/
					envelope_audioBufferSourceNode.loop = false;
				//}
				envelope_audioBufferSourceNode.connect(audioContext.destination);
				//console.log('duration', waveDuration);
				//envelope.audioBufferSourceNode.connect(envelope);
				//envelope.audioBufferSourceNode.start(startWhen, zone.delay);
				envelope_audioBufferSourceNode.start();
				//envelope_audioBufferSourceNode.stop(startWhen + waveDuration);
				//envelope.when = startWhen;
				//envelope.duration = waveDuration;
				//envelope.pitch = pitch;
				//envelope.preset = preset;
				//return envelope;
			};
			var selectedPreset=_tone_0000_SoundBlasterOld_sf2;
			var AudioContextFunc = window.AudioContext || window.webkitAudioContext;
			var audioContext = new AudioContextFunc();
			var clickCOunt=0;
			function playStart(){
				clickCOunt++;
				console.log('audioContext',audioContext);
				console.log('click '+14+'+'+clickCOunt);
				console.log('state '+audioContext.state);
				console.log('time '+audioContext.currentTime);
				console.log('latency '+audioContext.baseLatency);
				for(var i=0;i<selectedPreset.zones.length;i++){
					console.log(''+i+': '+selectedPreset.zones[i].sample.length);
				}
				var envelope=queueWaveTable(audioContext, audioContext.destination, selectedPreset, 0, 55, 3.5);
				//console.log('envelope',envelope);
			}
		</script>
	</head>
	<body>
		<h1><a href="#" onmousedown="playStart();">Test 17</a></h1>
		<hr/>

		<h2><button onclick="testo();">play</button></h2>
		<script>
			function testo(){
				console.log('start');
				var audioCtx = new (window.AudioContext || window.webkitAudioContext)();

				// create Oscillator node
				var oscillator = audioCtx.createOscillator();

				oscillator.type = 'square';
				oscillator.frequency.setValueAtTime(440, audioCtx.currentTime); // value in hertz
				oscillator.connect(audioCtx.destination);
				oscillator.start();
				console.log('started',oscillator);
			}
		</script>
	</body>
</html>